﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FluentFTP;
using Flurl.Http;
using Newtonsoft.Json.Linq;
using Pay.Core;
using Pay.Core.AlipayWap;
using Pay.Core.WeiXin;
using Pay.DTO;
using Pay.IService;
using Pay.TO;

namespace Pay.Service {
	/// <summary>
	/// SFB
	/// </summary>
	public class SfbPayService : ServiceBase2, IPayService, IDisposable {
		private ISettingService _iSettingService;
		private IMerchantService _iMerchantService;
		private IChargeService _iChargeService;
		private IRegionService _iRegionService;
		private ITransferService _iTransferService;
		private IProfitDayService _iProfitDayService;
		private IBillService _iBillService;
		private IPayHtmlService _iPayHtmlService;
		private IOrderService _iOrderService;
		private IPayNotifyService _iPayNotifyService;

		public SfbPayService(IUnitOfWork iUnitOfWork, ISettingService iSettingService,
								  IMerchantService iMerchantService, IChargeService iChargeService, IRegionService iRegionService,
								ITransferService iTransferService, IProfitDayService iProfitDayService, IBillService iBillService,
						   		IPayHtmlService iPayHtmlService, IOrderService iOrderService, IPayNotifyService iPayNotifyService) : base(iUnitOfWork) {
			_iSettingService = iSettingService;
			_iMerchantService = iMerchantService;
			_iChargeService = iChargeService;
			_iRegionService = iRegionService;
			_iTransferService = iTransferService;
			_iProfitDayService = iProfitDayService;
			_iBillService = iBillService;
			_iPayHtmlService = iPayHtmlService;
			_iOrderService = iOrderService;
			_iPayNotifyService = iPayNotifyService;
		}
		#region 扫码的
		/// <summary>
		/// HF扫码支付请求通道封装
		/// </summary>
		/// <returns>The pay gateway.</returns>
		/// <param name="model">Model.</param>
		/// <typeparam name="T">The 1st type parameter.</typeparam>
		public async Task<native_result> NativePay(native_model model) {
			var setting = _iSettingService.Get();
			var merchant = _iMerchantService.Get(model.merchant_no);
			//把商户请求转为通道请求消息
			var id = Guid.NewGuid().ToString("N");
			var notifyUrl = setting.site.api_url + "/sfb_native_notify/" + id;
			var pay_model = new payment_query();
			unifiedorder pay_rep = null;
			string alipay_info = string.Empty;
			if (model.pay_code == "WXPAY_JS") {
				pay_model = new payment_query { app_id = model.appid, app_secret = "", key = "", mchid = "" };
				pay_rep = await TenPayV3.Unifiedorder(pay_model, model.openid, model.body, model.order_no, model.tran_amount, notifyUrl);
			} else if (model.pay_code == "WXPAY_APP") {
				pay_model = new payment_query {
					app_id = merchant.setting.wx_app.app_id, app_secret = merchant.setting.wx_app.app_secret,
					key = "e590999272769b5d0e78726848f99ad7", mchid = merchant.setting.wx_app.mchid
				};
				pay_rep = await TenPayV3.Unifiedorder(pay_model, "", model.body, model.order_no, model.tran_amount, notifyUrl, "APP");
			} else if (model.pay_code == "WXPAY_QR") {
				pay_model = new payment_query { app_id = model.appid, app_secret = "", key = "", mchid = "" };
				pay_rep = await TenPayV3.Unifiedorder(pay_model, "", model.body, model.order_no, model.tran_amount, notifyUrl, "QR");
			} else if (model.pay_code == "ALIPAY_APP") {
				pay_model = new payment_query { app_id = model.appid, app_secret = "", key = "", mchid = "" };
				alipay_info = new PayApp().GetPayInfo(pay_model, model.body, model.order_no, decimal.Parse(model.tran_amount) / 100M, notifyUrl);
			}
			if (pay_rep != null) {
				//创建订单
				model.transaction_no = "";
				var charge = _iChargeService.AddByNativePay(model);
				//将HTML保存到mongodb
				var ok = _iPayHtmlService.Save(new pay_html_dto { id = id, html = "扫码等", merchant_no = model.merchant_no, order_no = model.order_no, charge = charge.ToJson() });
				if (ok) {
					native_result data = null;
					if (model.pay_code.Contains("WXPAY"))
						data = new native_result {
							code_url = pay_rep.code_url, order_no = model.order_no, pay_info = pay_rep.ToJson("code_url"), transaction_no = model.transaction_no
						};
					else if (model.pay_code.Contains("ALIPAY_APP"))
						data = new native_result {
							code_url = "", order_no = model.order_no, pay_info = alipay_info, transaction_no = model.transaction_no
						};
					return ApiResultToJson.Json(data);
				}
			}
			return await ApiResultToJson.JsonAsync<native_result>("支付请求失败");
		}
		#endregion

		#region 支付异步通知
		/// <summary>
		/// 回调支付通知，商户返回OK，不再回调了，流程是先调用ChargeService的NotifyOrder，
		/// 返回值判断是调用哪个通道，再调用本方法，最后调用ChargeService的Update
		/// </summary>
		/// <returns>The notify.</returns>
		/// <param name="order_no">Order.</param>
		public async Task<string> Notify(string merchant_no, string order_no) {
			string result = string.Empty;
			var order = _iChargeService.Get(merchant_no, order_no);
			if (order == null) return "OK";
			try {
				var data = new pay_notity {
					tran_amount = ((int)(order.order_amount * 100)).ToString(), order_no = order.order_no, transaction_no = order.pay_info.transaction_no,
					pay_time = order.pay_info.pay_time.HasValue ? order.pay_info.pay_time.Value : order.order_time,
					status = (order.status == ChargeStatus.Finish ? 1 : 2)
				};
				//失败的要再查询通道判断是否真失败,处理掉单
				if (order.status == ChargeStatus.Fail || order.status == ChargeStatus.UnConfirm) {
					if (order.pay_info.pay_code.Contains("WXPAY")) {
						var wx_app = order.merchant.setting.wx_app;
						var pay_model = new payment_query {
							app_id = wx_app.app_id, app_secret = wx_app.app_secret,
							key = "e590999272769b5d0e78726848f99ad7", mchid = wx_app.mchid
						};
						var pay_rep = await TenPayV3.OrderQuery(pay_model, "", order.order_no);
						if (pay_rep.trade_state == "SUCCESS") {
							data.status = 1;
							_iChargeService.FailOrUnConfirmToSuceess(merchant_no, order.order_no, pay_rep.transaction_end, pay_rep.transaction_id);
						} else
							order.fail = pay_rep.return_msg;
					} else if (order.pay_info.pay_code == "ALIPAY_APP") {
					}
				}
				data.result_msg = (data.status == 1 ? "支付成功" : order.fail);
				var notify_result = await order.notify.PostJsonAsync(ApiResultToJson.Json(data)).ReceiveJson<ResultMessage<string>>();
				result = notify_result.data;
				var log = IocHelper.Get<ILogHelper>("info");
				log.Info(order.order_no + ":" + notify_result.ToJson());
			} catch (Exception ex) {
				var log = IocHelper.Get<ILogHelper>("info");
				log.Error("订单通道查询异常:" + order.order_no);
				log.Error(ex.Message);
			}
			return result;
		}

		/// <summary>
		/// 代付通知
		/// </summary>
		/// <returns>The transfer.</returns>
		/// <param name="order_no">Order.</param>
		public Task<string> NotifyTransfer(string merchant_no, string order_no) {
			throw new NotImplementedException();
		}
		#endregion

		#region 没用到
		public Task<merchant_register_result> MerchantRegister(merchant_register_model dto, string opt) {
			throw new NotImplementedException();
		}

		public Task<merchant_register_result> MerchantRegister(long bind_id, string settle_type,PayChannel channel = PayChannel.None) {
			throw new NotImplementedException();
		}

		public Task<merchant_register_result> MerchantModify(long bind_id, string settle_type,PayChannel channel = PayChannel.None) {
			throw new NotImplementedException();
		}

		public Task<quota_result> Quota(string merchant_no, string busiType) {
			throw new NotImplementedException();
		}

		public Task<quick_pay_result> QuickPay(quick_pay_model model) {
			throw new NotImplementedException();
		}

		public Task<ApiResultMessage> QuickPaySendsms(quick_sendsms_model model) {
			throw new NotImplementedException();
		}

		public Task<quick_pay_result> QuickPay(quick_sms_model model) {
			throw new NotImplementedException();
		}

		public Task<pay_notity> QuickPayQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		public Task<refund_result> QuickPayRefund(refund_model model) {
			throw new NotImplementedException();
		}

		public Task<refund_result> QuickPayRefundQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		public List<type_setting> GatewayPayBank() {
			throw new NotImplementedException();
		}

		public Task<gateway_pay_result> GatewayPay(gateway_pay_model model) {
			throw new NotImplementedException();
		}

		public Task<pay_notity> GatewayPayQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		public Task<refund_result> GatewayPayRefund(refund_model model) {
			throw new NotImplementedException();
		}

		public Task<refund_result> GatewayRefundQuery(refund_model_query model) {
			throw new NotImplementedException();
		}

		public Task<transfer_result> Transfer(apply_transfer model) {
			throw new NotImplementedException();
		}

		public Task<transfer_result> ReTransfer(long id) {
			throw new NotImplementedException();
		}

		public Task<batch_transfer_result> Transfer(batch_transfer model) {
			throw new NotImplementedException();
		}

		public Task<int> TransferNotify(long batchId, string batchFileName, long merchant_id) {
			throw new NotImplementedException();
		}

		public Task<int> TransferBack(long batchId, string noticeTranId, long merchant_id) {
			throw new NotImplementedException();
		}

		public Task<transfer_result> TransferQuery(transfer_query model) {
			throw new NotImplementedException();
		}

		public Task<ApiResultMessage> InsteadReceive(verify_model model) {
			throw new NotImplementedException();
		}

		public Task<ApiResultMessage> InsteadReceive(verify_model_sms model) {
			throw new NotImplementedException();
		}

		public Task<transfer_result> AgencyFund(apply_receive model) {
			throw new NotImplementedException();
		}

		public Task<int> ItpToFile(DateTime create_date) {
			throw new NotImplementedException();
		}

		public int DealItp(long id) {
			throw new NotImplementedException();
		}

		public Task<certify_verify_result> CertifyVerify(certify_verify model) {
			throw new NotImplementedException();
		}
		#endregion
		/// <summary>
		/// 商城支付
		/// </summary>
		/// <param name="model"></param>
		/// <returns></returns>
		public async Task<mall_result> MallPay(mall_model model) {
			var id = Guid.NewGuid().ToString("N");
			var notifyUrl = string.Format("{0}/mall_notify/{1}", _iSettingService.Get().site.api_url, id);
			var shipping = new shipping_dto();
			if (model.shipping != null) {
				shipping.ship_to = model.shipping.ship_to;
				shipping.region_id = model.shipping.area_id.HasValue ? model.shipping.area_id.Value : model.shipping.city_id;
				shipping.phone = model.shipping.phone; shipping.address = model.shipping.address;
				shipping.region_name = model.shipping.region_name;
			}
			model.orders.ForEach(c => { c.shipping_type = model.shipping_type; c.shipping = shipping; });
			var charge = _iChargeService.AddByMallPay(model);
			var pay_html = new pay_html_dto {
				id = id, html = model.orders.ToJson(), merchant_no = model.merchant_no, order_no = model.order_no, charge = charge.ToJson()
			};
			var ok = _iPayHtmlService.Save(pay_html);
			if (ok) {
				//订单为全额积分抵扣不需要调起第三方微信支付
				if (charge.pay_amount == 0) {
					_iOrderService.PaySuceess(pay_html, "", DateTime.Now);
					var notifyResult = await Notify(charge.merchant_no, charge.order_no);
					if (notifyResult != "OK") {
						//创建通知消息对象
						_iPayNotifyService.Save(new pay_notify_dto {
							merchant_no = charge.merchant_no, order_no = charge.order_no, pay_channel = charge.pay_info.pay_channel, type = 1,
							status = 2, create_time = DateTime.Now
						});
						return ApiResultToJson.Json(new mall_result { order_no = model.order_no, transaction_no = model.transaction_no, is_open = false });
					}
					return ApiResultToJson.Json<mall_result>("订单异步通知异常");
				} else {
					if (model.pay_code == "WXPAY_APP") {
#if DEBUG
						_iOrderService.PaySuceess(pay_html, "", DateTime.Now);
						var notifyResult = await Notify(charge.merchant_no, charge.order_no);
						if (notifyResult != "OK") {
							//创建通知消息对象
							_iPayNotifyService.Save(new pay_notify_dto {
								merchant_no = charge.merchant_no, order_no = charge.order_no, pay_channel = charge.pay_info.pay_channel, type = 1,
								status = 2, create_time = DateTime.Now
							});
						}
						_iPayHtmlService.Remove(id);
						return ApiResultToJson.Json(new mall_result { order_no = model.order_no, transaction_no = model.transaction_no, is_open = false });
#else
						var merchant = _iMerchantService.Get(model.merchant_no);
						var pay_model = new payment_query {
							app_id = merchant.setting.wx_app.app_id, app_secret = merchant.setting.wx_app.app_secret,
							key = "e590999272769b5d0e78726848f99ad7", mchid = merchant.setting.wx_app.mchid
						};
						var pay_rep = await TenPayV3.Unifiedorder(pay_model, "", model.body, model.order_no, model.tran_amount, notifyUrl, "APP");
						if (pay_rep != null) {
							//创建订单
							model.transaction_no = "";
							mall_result data = null;
							if (model.pay_code.Contains("WXPAY"))
								data = new mall_result {
									code_url = pay_rep.code_url, order_no = model.order_no, pay_info = pay_rep.ToJson("code_url"),
									transaction_no = model.transaction_no, is_open = true
								};
							return ApiResultToJson.Json(data);
						}
#endif
					}
				}
			}
			return await ApiResultToJson.JsonAsync<mall_result>("支付请求失败");
		}

        public Task<transfer_result> TokenTransfer(long id) {
            throw new NotImplementedException();
        }

        public Task<transfer_result> TokenTransferQuery(transfer_query model) {
            throw new NotImplementedException();
        }
    }
}